function BilibiliParser(t) {
    function i(t) {
        return t.replace(/\t/, "\\t")
    }
    for (var e = t.getElementsByTagName("d"), o = [], s = 0; s < e.length; s++)
        if (null != e[s].getAttribute("p")) {
            var n = e[s].getAttribute("p").split(",");
            if (!e[s].childNodes[0]) continue;
            var h = e[s].childNodes[0].nodeValue,
                r = {};
            if (r.stime = Math.round(1e3 * parseFloat(n[0])), r.mode = parseInt(n[1]), r.size = parseInt(n[2]), r.color = parseInt(n[3]), r.date = parseInt(n[4]), r.pool = parseInt(n[5]), r.position = "absolute", null != n[7] && (r.dbid = parseInt(n[7])), r.hash = n[6], r.border = !1, r.mode < 7) r.text = h.replace(/(\/n|\\n|\n|\r\n)/g, "\n");
            else if (7 == r.mode) try {
                if (adv = JSON.parse(i(h)), r.shadow = !0, r.x = parseFloat(adv[0]), r.y = parseFloat(adv[1]), (Math.floor(r.x) < r.x || Math.floor(r.y) < r.y) && (r.position = "relative"), r.text = adv[4].replace(/(\/n|\\n|\n|\r\n)/g, "\n"), r.rZ = 0, r.rY = 0, adv.length >= 7 && (r.rZ = parseInt(adv[5], 10), r.rY = parseInt(adv[6], 10)), r.motion = [], r.movable = !1, adv.length >= 11) {
                    r.movable = !0;
                    var a = 500,
                        f = {
                            x: {
                                from: r.x,
                                to: parseFloat(adv[7]),
                                dur: a,
                                delay: 0
                            },
                            y: {
                                from: r.y,
                                to: parseFloat(adv[8]),
                                dur: a,
                                delay: 0
                            }
                        };
                    if ("" !== adv[9] && (a = parseInt(adv[9], 10), f.x.dur = a, f.y.dur = a), "" !== adv[10] && (f.x.delay = parseInt(adv[10], 10), f.y.delay = parseInt(adv[10], 10)), adv.length > 11 && (r.shadow = adv[11], "true" === r.shadow && (r.shadow = !0), "false" === r.shadow && (r.shadow = !1), null != adv[12] && (r.font = adv[12]), adv.length > 14)) {
                        "relative" === r.position && (console.log("Cannot mix relative and absolute positioning"), r.position = "absolute");
                        for (var m = adv[14], l = {
                                x: f.x.from,
                                y: f.y.from
                            }, d = [], p = new RegExp("([a-zA-Z])\\s*(\\d+)[, ](\\d+)", "g"), u = m.split(/[a-zA-Z]/).length - 1, c = p.exec(m); null !== c;) {
                            switch (c[1]) {
                                case "M":
                                    l.x = parseInt(c[2], 10), l.y = parseInt(c[3], 10);
                                    break;
                                case "L":
                                    d.push({
                                        x: {
                                            from: l.x,
                                            to: parseInt(c[2], 10),
                                            dur: a / u,
                                            delay: 0
                                        },
                                        y: {
                                            from: l.y,
                                            to: parseInt(c[3], 10),
                                            dur: a / u,
                                            delay: 0
                                        }
                                    }), l.x = parseInt(c[2], 10), l.y = parseInt(c[3], 10)
                            }
                            c = p.exec(m)
                        }
                        f = null, r.motion = d
                    }
                    null !== f && r.motion.push(f)
                }
                r.dur = 2500, adv[3] < 12 && (r.dur = 1e3 * adv[3]);
                var g = adv[2].split("-");
                if (null != g && g.length > 1) {
                    var y = parseFloat(g[0]),
                        v = parseFloat(g[1]);
                    r.opacity = y, y !== v && (r.alpha = {
                        from: y,
                        to: v
                    })
                }
            } catch (w) {
                console.log("[Err] Error occurred in JSON parsing"), console.log("[Dbg] " + h)
            } else 8 == r.mode && (r.code = h);
            null != r.text && (r.text = r.text.replace(/\u25a0/g, "█")), o.push(r)
        } return o
}

function CommentManager(t) {
    this.stage = t, this.options = {
        indexOffset: 0,
        className: "cmt",
        margin: 1,
        fresh: 10,
        global: {
            opacity: 1,
            scale: 1
        },
        scroll: {
            opacity: 1,
            scale: 1
        },
        limit: 0,
        newSetting: !0
    }, this.commentLine = [], this.nowLine = [], this.position = 0, this.width = t.offsetWidth, this.height = t.offsetHeight, this.startTimer = function () {
        for (var t = 0; t < this.nowLine.length; t++) this.nowLine[t].control && this.nowLine[t].start()
    }, this.stopTimer = function () {
        for (var t = 0; t < this.nowLine.length; t++) this.nowLine[t].control && this.nowLine[t].stop()
    }, this.nowLinePush = function (t) {
        if (0 === this.nowLine.length) return void this.nowLine.push(t);
        if (this.nowLine[this.nowLine.length - 1].offsetY() <= t.offsetY()) return void this.nowLine.push(t);
        if (this.nowLine[0].offsetY() >= t.offsetY()) return void this.nowLine.unshift(t);
        for (var i = 0, e = this.nowLine.length - 1, o = 0, s = 0; i < e;) {
            if (o = Math.floor((e + i + 1) / 2), this.nowLine[o - 1].offsetY() <= t.offsetY() && this.nowLine[o].offsetY() >= t.offsetY()) {
                s = o;
                break
            }
            this.nowLine[o - 1].offsetY() > t.offsetY() ? e = o - 1 : i = o
        }
        this.nowLine.splice(s, 0, t)
    }, this.nowLineRemove = function (t) {
        var i = this.nowLine.indexOf(t);
        i >= 0 && this.nowLine.splice(i, 1)
    }, this.setBounds = function () {
        this.width = this.stage.offsetWidth, this.height = this.stage.offsetHeight
    }, this.init = function () {
        this.setBounds(), this.position = 0
    }, this.send = function (t) {
        var i;
        if (5 === t.mode || 4 === t.mode) i = new StaticComment(this, t);
        else {
            if (1 !== t.mode && 2 !== t.mode && 6 != t.mode) return void console.log("不支持的弹幕");
            i = new ScrollComment(this, t)
        }
        i.init(), i.layout() && (i.insert(this.stage), this.nowLinePush(i))
    }, this.seek = function (t) {
        this.position = 0, this.position = this.locate(t)
    }, this.locate = function (t) {
        for (var i = this.position; i < this.commentLine.length; i++) {
            var e = this.commentLine[i];
            if (e.stime >= t) return i
        }
        return this.commentLine.length
    }, this.time = function (t) {
        if (0 !== this.nowLine.length || this.position !== this.commentLine.length) {
            if (t -= 1, this.position < this.commentLine.length) {
                for (var i = this.locate(t); this.position < i; this.position++) this.options.limit > 0 && this.nowLine.length >= this.options.limit || this.send(this.commentLine[this.position]);
                this.position = i
            }
            for (var e = this.nowLine.length, o = 0; o < e; o++) {
                var s = this.nowLine[o];
                s.checkTime(t) || (this.remove(s), e--)
            }
        }
    }, this.setOpacity = function (t) {
        "number" == typeof t && (this.stage.style.opacity = t / 100)
    }, this.setSpeed = function (t) {
        "number" == typeof t && (this.options.scroll.scale = Math.min(Math.max(2 - t / 200, .1), 2))
    }, this.setLimit = function (t) {
        "number" == typeof t && (this.options.limit = Math.min(Math.max(t, 20), 200))
    }, this.load = function (t) {
        this.commentLine = t, this.position = 0, this.commentLine.sort(function (t, i) {
            return t.stime >= i.stime ? 1 : -1
        })
    }, this.remove = function (t) {
        this.nowLineRemove(t), this.stage.removeChild(t.dom)
    }, this.clear = function () {
        for (; this.nowLine.length > 0;) this.remove(this.nowLine[0])
    }
}
var __extends = function (t, i) {
        var e = function () {};
        e.prototype = i.prototype;
        var o = new e;
        o.constructor = t, t.prototype = o
    },
    CommentObject = function () {
        function t(t, i) {
            this.align = 0, this.index = 0, this.mode = 1, this.stime = 0, this.text = "", this.lifeTime = 12e3 * t.options.global.scale, this._size = 25, this._color = 16777215, this.manager = t, this.control = !1, this._border = !1, i.hasOwnProperty("align") && (this.align = i.align), i.hasOwnProperty("stime") && (this.stime = i.stime), i.hasOwnProperty("text") && (this.text = i.text), i.hasOwnProperty("mode") && (this.mode = i.mode), i.hasOwnProperty("color") && (this._color = i.color), i.hasOwnProperty("size") && (this._size = i.size), i.hasOwnProperty("x") && (this._x = i.x), i.hasOwnProperty("y") && (this._y = i.y), i.hasOwnProperty("border") && (this._border = i.border)
        }
        return t.prototype.offsetX = function (t) {
            return null === t || void 0 === t ? (null !== this._x && void 0 !== this._x || (this.align % 2 === 0 ? this._x = this.dom.offsetLeft - this.manager.stage.offsetLeft : this._x = this.manager.stage.offsetWidth - (this.dom.offsetLeft - this.manager.stage.offsetLeft + this.dom.offsetWidth)), this._x) : (this._x = t, void(this.dom && (this.align % 2 === 0 ? this.dom.style.right = this._x + "px" : this.dom.style.left = this._x + "px")))
        }, t.prototype.offsetY = function (t) {
            return null === t || void 0 === t ? (null !== this._y && void 0 !== this._y || (this.align < 2 ? this._y = this.dom.offsetTop : this._y = this.manager.stage.offsetHeight - (this.dom.offsetTop + this.dom.offsetHeight)), this._y) : (this._y = t, void(this.dom && (this.align < 2 ? this.dom.style.top = this._y + "px" : this.dom.style.top = this.manager.stage.offsetHeight - t - this.dom.offsetHeight + "px")))
        }, t.prototype.Color = function (t) {
            if (null === t || void 0 === t) return this._color;
            this._color = t;
            var i = t.toString(16);
            i = i.length >= 6 ? i : new Array(6 - i.length + 1).join("0") + i, 0 !== i.indexOf("#") && (i = "#".concat(i)), this.dom.style.color = i, 0 === this._color && (this.dom.className = this.manager.options.className + " rshadow")
        }, t.prototype.Width = function (t) {
            return null === t || void 0 === t ? (null !== this._width && void 0 !== this._width || (this._width = this.dom.offsetWidth), this._width) : (this._width = t, void(this.dom.style.width = this._width + "px"))
        }, t.prototype.Height = function (t) {
            return null === t || void 0 === t ? (null !== this._height && void 0 !== this._height || (this._height = this.dom.offsetHeight), this._height) : (this._height = t, void(this.dom.style.height = this._height + "px"))
        }, t.prototype.Size = function (t) {
            return null === t || void 0 === t ? this._size : (this._size = t, void(this.dom.style.fontSize = this._size + "px"))
        }, t.prototype.Border = function (t) {
            return null === t || void 0 === t ? this._border : (this._border = t, void(this.dom.style.border = t))
        }, t.prototype.init = function () {
            this._height = this._size + 3
        }, t.prototype.checkTime = function (t) {
            return this.stime + this.lifeTime >= t
        }, t.prototype.layout = function () {}, t.prototype.insert = function (t) {
            var i = document.createElement("div");
            i.className = this.manager.options.className, i.appendChild(document.createTextNode(this.text)), i.textContent = this.text, i.innerText = this.text, this.dom = i, this._border && (i.style.border = "2px solid red"), this.Color(this._color), this.Size(this._size), t.appendChild(this.dom), this._height = this.dom.offsetHeight, this.offsetY(this._y)
        }, t.prototype.stop = function () {}, t.prototype.start = function () {}, t
    }(),
    ScrollComment = function (t) {
        function i(t) {
            return t.replace(/-(\w)/g, function (t, i) {
                return i.toUpperCase()
            })
        }

        function e(t) {
            var e, o = ["webkit", "moz", "ms", "o"],
                s = [],
                n = document.documentElement.style;
            for (e in o) s.push(i(o[e] + "-" + t));
            s.push(i(t));
            for (e in s)
                if (s[e] in n) return !0;
            return !1
        }

        function o(i, e) {
            switch (t.call(this, i, e), this.mode) {
                case 1:
                    this.align = 0;
                    break;
                case 2:
                    this.align = 2;
                    break;
                case 6:
                    this.align = 1
            }
            this.follow = !1, this.control = !0, this._lifeTime = this.lifeTime, this.lifeTime *= i.options.scroll.scale, this.timeLeft = this.lifeTime, this.moving = !1, this.manager.options.newSetting && (this._width = this._size * this.text.replace(/[^\x00-\xff]/gi, "sm").length / 2)
        }
        return __extends(o, t), o.SUPPORT_ANIMATION = !e("transition"), o.MAX_LAYERS = 1, o.prototype._findOffsetY = function (t, i, e) {
            for (var o, s = e, n = 0; n < this.manager.nowLine.length; n++)
                if (o = this.manager.nowLine[n], o.mode === this.mode && o.index === t) {
                    if (o.offsetY() - s >= i) return s;
                    if (!o.follow && o.timeLeft <= .5 * o.lifeTime) return o.follow = !0, o.offsetY();
                    s = o.offsetY() + o.Height()
                } return s + i <= this.manager.stage.offsetHeight ? s : -1
        }, o.prototype._nfindOffsetY = function (t, i, e) {
            for (var o, s = Math.max(Math.min(this.manager.options.limit || 100, 100) / 100 * this.manager.stage.offsetHeight, i), n = this.manager.width, h = this.Width() + (24 - (this.manager.options.limit || 100) / 10), r = h / ((h + n) / this.lifeTime), a = e, f = 0; f < this.manager.nowLine.length; f++)
                if (o = this.manager.nowLine[f], o.mode === this.mode && o.index === t) {
                    if (o.offsetY() - a >= i && a <= s) return a;
                    var m = o.lifeTime - o.timeLeft,
                        l = m * (n + o.Width()) / this.lifeTime;
                    if (!o.follow && l > o.Width() && m > r && o.offsetY() <= s) return o.follow = !0, o.offsetY();
                    a = o.offsetY() + o.Height()
                } return a + i <= s ? a : -1
        }, o.prototype.checkTime = function (i) {
            return this.timeLeft = this.stime + this.lifeTime - i, t.prototype.checkTime.call(this, i)
        }, o.prototype.layout = function () {
            for (var t = 0, i = this.Size() + 2 * this.manager.options.margin, e = 0, s = -1; s < 0 && t < o.MAX_LAYERS;) s = this.manager.options.newSetting ? this._nfindOffsetY(t, i, e) : this._findOffsetY(t, i, e), t++, e += this.manager.options.indexOffset;
            return !(s < 0) && (this.index = t - 1, this.offsetY(s), !0)
        }, o.prototype.insert = function (i) {
            t.prototype.insert.call(this, i), this.offsetX(-this.Width()), this.move()
        }, o.prototype.transform = function (t) {
            this.dom.style.webkitTransform = t, this.dom.style.mozTransform = t, this.dom.style.msTransform = t, this.dom.style.oTransform = t, this.dom.style.transform = t
        }, o.prototype.transition = function (t) {
            this.dom.style.webkitTransition = "-webkit-" + t, this.dom.style.mozTransition = "-moz-" + t, this.dom.style.msTransition = "-ms-" + t, this.dom.style.oTransition = "-o-" + t, this.dom.style.transition = t
        }, o.prototype.moveTransform = function () {
            var t = -(this.manager.width + this.Width());
            this.transition("transform " + this.lifeTime + "ms linear"), this.transform("translateX(" + t + "px)")
        }, o.prototype.startTransform = function () {
            var t = -(this.timeLeft / this.lifeTime * (this.manager.width + this.Width()));
            this.transition("transform " + this.timeLeft + "ms linear"), this.transform("translateX(" + t + "px)")
        }, o.prototype.stopTransform = function () {
            if (this.moving) {
                var t = this.Width(),
                    i = (1 - this.timeLeft / this.lifeTime) * (this.manager.width + t) - t;
                this.offsetX(i), this.transform(""), this.transition(""), this.moving = !1
            }
        }, o.prototype.moveAnimation = function () {
            var t = this.align % 2 == 0 ? "-left" : "-right",
                i = this.lifeTime / 1e3 + "s";
            this.dom.className += " move" + t, this.dom.style["-webkit-animation-duration"] = i, this.dom.style["-moz-animation-duration"] = i, this.dom.style["-o-animation-duration"] = i, this.dom.style["animation-duration"] = i
        }, o.prototype.startAnimation = function () {
            this.dom.style["-webkit-animation-play-state"] = "running", this.dom.style["-moz-animation-play-state"] = "running", this.dom.style["-o-animation-play-state"] = "running", this.dom.style["animation-play-state"] = "running"
        }, o.prototype.stopAnimation = function () {
            this.dom.style["-webkit-animation-play-state"] = "paused", this.dom.style["-moz-animation-play-state"] = "paused", this.dom.style["-o-animation-play-state"] = "paused", this.dom.style["animation-play-state"] = "paused"
        }, o.prototype.move = function () {
            this.moving || (o.SUPPORT_ANIMATION ? this.moveAnimation() : this.moveTransform(), this.moving = !0)
        }, o.prototype.start = function () {
            this.moving || (o.SUPPORT_ANIMATION ? this.startAnimation() : this.startTransform(), this.moving = !0)
        }, o.prototype.stop = function () {
            this.moving && (o.SUPPORT_ANIMATION ? this.stopAnimation() : this.stopTransform(), this.moving = !1)
        }, o.prototype.update = function () {
            if (!o.SUPPORT_ANIMATION) {
                var t = this.moving;
                this.moving = !1, this.stop();
                var i = this._lifeTime * this.manager.options.scroll.scale;
                this.timeLeft = Math.ceil(this.timeLeft * i / this.lifeTime), this.lifeTime = i, t && this.start()
            }
        }, o
    }(CommentObject),
    StaticComment = function (t) {
        function i(i, e) {
            t.call(this, i, e), this.align = 4 == this.mode ? 3 : 0, this.lifeTime = 4e3 * i.options.global.scale
        }
        return __extends(i, t), i.prototype._findOffsetY = function (t, i, e) {
            var o = e;
            for (var s in this.manager.nowLine) {
                var n = this.manager.nowLine[s];
                if (n.mode === this.mode && n.index === t) {
                    if (n.offsetY() - o >= i) return o;
                    o = n.offsetY() + n.Height()
                }
            }
            var h = (this.manager.options.limit || 100) / 200 * this.manager.stage.offsetHeight;
            return o + i <= h ? o : -1
        }, i.MAX_LAYERS = 1, i.prototype.layout = function () {
            for (var t = 0, e = this.Height() + 2 * this.manager.options.margin, o = 0, s = -1; s < 0 && t < i.MAX_LAYERS;) s = this._findOffsetY(t, e, o), t++, o += this.manager.options.indexOffset;
            return !(s < 0) && (this.index = t - 1, this.offsetY(s), !0)
        }, i.prototype.insert = function (i) {
            t.prototype.insert.call(this, i), this.offsetX(this.manager.stage.offsetLeft + (this.manager.stage.offsetWidth - this.Width()) / 2)
        }, i.prototype.update = function () {
            this.offsetX(this.manager.stage.offsetLeft + (this.manager.stage.offsetWidth - this.Width()) / 2)
        }, i
    }(CommentObject);